package br.com.sgi.bean;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.faces.model.SelectItem;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import br.com.sgi.enuns.EnumStatus;
import br.com.sgi.enuns.TipoAdmissaoEnum;
import br.com.sgi.enuns.TipoConsagracaoMinisterialEnum;
import br.com.sgi.enuns.UfEnum;
import br.com.sgi.model.Funcao;
import br.com.sgi.model.Igreja;
import br.com.sgi.model.Membro;
import br.com.sgi.model.MembroFuncao;
import br.com.sgi.model.Visitante;
import br.com.sgi.service.FuncaoService;
import br.com.sgi.service.IgrejaService;
import br.com.sgi.service.MembroFuncaoService;
import br.com.sgi.service.MembroService;
import br.com.sgi.service.VisitanteService;
import br.com.sgi.util.Constante;
import br.com.sgi.util.DateUtil;
import br.com.sgi.util.File;
import br.com.sgi.util.FileUploadBean;
import br.com.sgi.util.Mensagem;

@Controller("membroCadastro")
@Scope("request")
public class MembroCadastroBean extends BaseView {


	private static final long serialVersionUID = -6157734882789029886L;
	
	private  File file;
	 
	
	 
	private boolean registrosEncontrados;
	
	private Visitante visitante;
	
	@Autowired
	private VisitanteService visitanteService;
	
	

	@Autowired
	private IgrejaService igrejaService;
	
	@Autowired
	private FuncaoService funcaoService;
	
	@Autowired
	private MembroFuncaoService membroFuncaoService;
	
	@Autowired
	private MembroService membroService;
	
	@Autowired
	private FileUploadBean fileUploadBean;
	
	private List<Igreja> listaIgreja;
	private List<Funcao> listaFuncao;
	private List<Funcao> listaFuncaoExerce;
	private List<Funcao> listaFuncaoPretendida;
	private List<SelectItem> listaUfs;
	private List<TipoAdmissaoEnum> listaTipoAdmissao;
	private List<Membro> listaMembros;
	
	private Membro membro;
	private String codigo;
	private Funcao funcaoExerce;
	private Funcao funcaoPretendida;
	private Funcao funcao;
	private Long coMembro;
	private int qtFuncaoExerce;
	private int qtFuncaoPretendida;
	
	private Membro membroPesquisa;
	private boolean exibirMensagem;
	
	private String status;
	/**
	 * autualiza funcao
	 * @param listaFuncao
	 * @param tipoFuncao
	 */
	private void atualizarMembroFuncoes(List<Funcao> listaFuncao, String tipoFuncao, Long coMembro){
		
		List<MembroFuncao> membroFuncoes = membroFuncaoService.buscarMembroFuncaoPorCoMembro(coMembro, tipoFuncao);
		if(membroFuncoes != null && membroFuncoes.size() > 0)
			for(MembroFuncao mf: membroFuncoes){
				membroFuncaoService.excluir(mf.getCoSeqoMebroFuncao());
			}
		
		for(Funcao funcao : listaFuncao){
			MembroFuncao membroFuncao = new MembroFuncao();
			membroFuncao.setFuncao(funcao);
			membroFuncao.setStMembroFuncao(tipoFuncao);
			membroFuncao.setMembro(membro);
			membroFuncaoService.salvar(membroFuncao);
		}
	}
	
	/**
	 * voltar a tela de pesquisa
	 */
	public void voltar(){
		limparDados();
		statusBotoesPesquisa();
	}
	
	
	/**
	 * salvar Membro
	 */
	public void salvar(){
			
		if(validarDatas()){
			
			
			if(file != null){				
				membro.setFoto(file.getData());
			}
			
			if(membro.getCoSeqMembro() == null){
				membro.setDtCadastro(DateUtil.getDateNow());
				membro.setInativo(false);
				membroService.salvar(membro);
				if(visitante != null){
					visitante.setInativo(true);
					visitante.seteMembro("S");
					visitanteService.atualizar(visitante);
				}
				
				Mensagem.infoMsg("sucesso.MGS_02");
				super.statusBotoesPesquisa();
			}else{
				membro.setDtAtualizacao(DateUtil.getDateNow());
				membroService.atualizar(membro);
				Mensagem.infoMsg("sucesso.MGS_03");
				super.statusBotoesPesquisa();
			}
			
			if(listaFuncaoExerce != null)
				atualizarMembroFuncoes(listaFuncaoExerce, Constante.FUNCAO_EXERCE, membro.getCoSeqMembro());
			if(listaFuncaoPretendida != null)
				atualizarMembroFuncoes(listaFuncaoPretendida, Constante.FUNCAO_PRETENDE, membro.getCoSeqMembro());
			
			limparDados();
			pesquisar();
		}
		
		
	
	}
	

	public Membro getMembro() {
		if(membro == null)
			membro =  new Membro();
		return membro;
	}
	
	/**
	 * carrega a lista de funcoes e redireciona para edicao de um membro
	 */
	public String redirectMembro(){
		List<MembroFuncao> mFuncoesExerce = membroFuncaoService.buscarMembroFuncaoPorCoMembro(membro.getCoSeqMembro(), Constante.FUNCAO_EXERCE);
		listaFuncaoExerce = new ArrayList<Funcao>();
		
		getFile().setData(membro.getFoto());
		
		for(MembroFuncao mf: mFuncoesExerce){
			
			listaFuncaoExerce.add(mf.getFuncao());
		}
		List<MembroFuncao> mFuncoesPretende = membroFuncaoService.buscarMembroFuncaoPorCoMembro(membro.getCoSeqMembro(), Constante.FUNCAO_PRETENDE); 
		listaFuncaoPretendida = new ArrayList<Funcao>();
		for(MembroFuncao mf: mFuncoesPretende){
			listaFuncaoPretendida.add(mf.getFuncao());
		}
		
		carregarFuncoes();
		
		return "membroCadastroEdicao";
	}
	
	/**
	 * Inicia tela para um novo cadastro
	 * @return
	 */
	public void novo(){
		statusBotoesCadastro();
		membro = new Membro();
	}
	

	/**
	 * adiciona funcao exercidas
	 * @param funcaoExerce
	 */
	public void adicioarFuncaoExerce(){
		if(listaFuncaoExerce == null)
			listaFuncaoExerce = new ArrayList<Funcao>();
		
		if(funcaoExerce != null){	
			if(!funcaoRepitida(listaFuncaoExerce,funcaoExerce)){
				listaFuncaoExerce.add(funcaoExerce);
				qtFuncaoExerce = listaFuncaoExerce.size();
			}else{
				Mensagem.errorMsg("erro.MSG_02");
				exibirMensagem = true;
			}
		}
		else{
			Mensagem.errorMsg("erro.MSG_01");
			exibirMensagem = true;
		}
	}
	
	/**
	 * Remover funcao exerce
	 */
	public void removerFuncaoExerce(){
		if(funcao != null){
			listaFuncaoExerce.remove(funcao);
			qtFuncaoExerce = listaFuncaoExerce.size();
		}
	}

	/**
	 * adiciona funcao pretendida
	 * @param funcaoExerce
	 */
	public void adicioarFuncaoPretendida(){
		if(listaFuncaoPretendida == null)
			listaFuncaoPretendida = new ArrayList<Funcao>();
		
		if(funcaoPretendida != null){
			if(!funcaoRepitida(listaFuncaoPretendida,funcaoPretendida)){
				listaFuncaoPretendida.add(funcaoPretendida);
				qtFuncaoPretendida = listaFuncaoPretendida.size();
			}else{
				Mensagem.errorMsg("erro.MSG_02");
				exibirMensagem = true;
			}
		}
		else{
			Mensagem.errorMsg("erro.MSG_01");
			exibirMensagem = true;
		}
	}
	
	/**
	 * verifica se a funcao ja foi adicionada
	 * @param funcoes
	 * @param funcaoAdicionar
	 * @return
	 */
	private boolean funcaoRepitida(List<Funcao> funcoes, Funcao funcaoAdicionar){
		boolean jaExiste = false;
		for(Funcao funcao: funcoes){
			if(funcao.getCoSeqFuncao().equals(funcaoAdicionar.getCoSeqFuncao())){
				jaExiste = true;
				break;
			}
		}
		return jaExiste;
	}
	
	/**
	 * Remover funcao pretendida
	 */
	public void removerFuncaoPretendida(){
		if(funcao != null ){
			listaFuncaoPretendida.remove(funcao);
			qtFuncaoPretendida = listaFuncaoPretendida.size();
		}
	}
	
	/**
	 * retorna a funcao 
	 * @param listFuncao
	 * @param idFuncao
	 * @return
	 */
	private Funcao obterFuncao(List<Funcao> listFuncao, Long idFuncao){
		Funcao funcaoEcontrada = null;
		for(Funcao funcao: listFuncao){
			if(funcao.getCoSeqFuncao().equals(idFuncao)){
				funcaoEcontrada = funcao;
				break;
			}
		}
		return funcaoEcontrada;
	}
	
	public void limpar(){
		membro = new Membro();
		
	}
	
	private void limparDados(){
		membro = new Membro();
		listaFuncaoExerce = new ArrayList<Funcao>();
		listaFuncaoPretendida = new ArrayList<Funcao>();
		listaFuncao = new ArrayList<Funcao>();
		file = new File();
		fileUploadBean.clearUploadData();
	}
	
	public void pesquisar(){
		listaMembros = membroService.buscarMembroPorParametros(membroPesquisa, status);
		
		if(listaMembros.isEmpty()){
			//Mensagem.errorMsg("info.MGS_01");
			registroNaoEncontrado = true;
		}
			
	}
	
	/**
	 * torna visitante em um membro
	 */
	public String tornarMembro(){
		
		
		membro = new Membro();
		membro.setNome(visitante.getNome());
		membro.setCelular(visitante.getCelular());
		membro.setDtNascimento(visitante.getDtNascimento());
		membro.setIgrejaPertence(visitante.getIgrejaPertence());
		membro.setTelefone(visitante.getTelefone());
		membro.setSexo(visitante.getSexo());
		membro.setEstadoCivil(visitante.getEstadoCivil());
		statusBotoesCadastro();
		
		return "membroCadastroEdicao";
	}
	
	
	/**
	 * realiza a exclucao de uma membro
	 */
	public void excluir(){
		try {
			if(coMembro != null){
				membroService.excluir(coMembro);
				pesquisar();			
				Mensagem.infoMsg("sucesso.MSG_01");
				statusBotoesPesquisa();
			}	
		} catch (Exception e) {
			List<String> visitantes = visitanteService.visitantePorMembroResponsavel(membro.getCoSeqMembro());
			StringBuilder noVisitantes = new StringBuilder();
			int cont = 0;
			for(String noVisitante:visitantes){
				cont++;
				noVisitantes.append(noVisitante);
				if(cont < visitantes.size())
					noVisitantes.append("; ");
				
			}
			Mensagem.addWarn("erro.MSG_17", membro.getNome(),noVisitantes.toString());
		}
			
	}
	
	public void editar(){
		statusEditar();
		redirectMembro();
		
	}
	
	private boolean validarDatas(){
		Date dtNascimento = membro.getDtNascimento();
		boolean datasValidas = true;
		if(membro.getDtBatismo() != null ){
			if(membro.getDtBatismo().compareTo(dtNascimento) < 0 ){
				String[] campos = {"Data Batismo","Data Nascimento"};
				Mensagem.addWarn("erro.MSG_04", "Data Batismo","Data Nascimento");
				datasValidas = false;
			}
			
			if(membro.getDtConversao()!= null && membro.getDtConversao() != null && membro.getDtConversao().compareTo(membro.getDtBatismo()) > 0 ){
				String[] campos = {"Data Batismo","Data Conversão"};
				Mensagem.addWarn("erro.MSG_04", "Data Batismo","Data Conversão");
				datasValidas = false;
			}
			
		}
		if(membro.getDtBatismo()!= null && membro.getDtBatismo().compareTo(dtNascimento) < 0 ){
			Mensagem.addWarn("erro.MSG_04", "Data Batismo", "Data Nascimento");
			datasValidas = false;
		}else
			if(membro.getDtCasamento()!= null && membro.getDtCasamento().compareTo(dtNascimento) < 0 ){
				Mensagem.addWarn("erro.MSG_04", "Data Casamento", "Data Nascimento");
				datasValidas = false;
			}else
				if(membro.getDtConversao()!= null && membro.getDtConversao().compareTo(dtNascimento) < 0 ){
					Mensagem.addWarn("erro.MSG_04", "Data Conversão", "Data Nascimento");
					datasValidas = false;
				}else
					if(membro.getDtConsagracaoMinist()!= null && membro.getDtConsagracaoMinist().compareTo(dtNascimento) < 0 ){
						Mensagem.addWarn("erro.MSG_04", "Data Consagração Minsiterial", "Data Nascimento");
						datasValidas = false;
					}else
					if(membro.getDtConsagracaoMinist()!= null && membro.getDtConversao()!= null && membro.getDtConsagracaoMinist().compareTo( membro.getDtConversao()) < 0 ){
						Mensagem.addWarn("erro.MSG_04", "Data Consagração Minsiterial", "Data Conversão");
						datasValidas = false;
					}else
						if(membro.getDtAdmissao()!= null && membro.getDtAdmissao().compareTo(dtNascimento) < 0 ){
							Mensagem.addWarn("erro.MSG_04", "Data Admissão", "Data Nascimento");
							datasValidas = false;
						}
							
		return datasValidas;
	}
	
	public void carregarFuncoes(){
		if(membro.getIgrejaPertence() != null)
			listaFuncao = funcaoService.buscarFuncoesPorIgreja(membro.getIgrejaPertence().getCoSeqIgreja());
	}

	public List<Membro> getListaMembros() {
		if(listaMembros == null)
			listaMembros =  new ArrayList<Membro>();//membroService.buscarMembroPorParametros(new Membro());
		return listaMembros;
	}

	public void setListaMembros(List<Membro> listaMembros) {
		this.listaMembros = listaMembros;
	}


	public Membro getMembroPesquisa() {
		if(membroPesquisa == null)
			membroPesquisa = new Membro();
		return membroPesquisa;
	}

	public void setMembroPesquisa(Membro membroPesquisa) {
		this.membroPesquisa = membroPesquisa;
	}
	
	
	
	public List<Funcao> getListaFuncao() {
		if(listaFuncao == null){
			listaFuncao = new ArrayList<Funcao>();
		}
		return listaFuncao;
	}


	public void setListaFuncao(List<Funcao> listaFuncao) {
		this.listaFuncao = listaFuncao;
	}


	public void setMembro(Membro membro) {
		this.membro = membro;
	}

	public String getCodigo() {
		return codigo;
	}

	public void setCodigo(String codigo) {
		this.codigo = codigo;
	}

	public List<Igreja> getListaIgreja() {
		if(listaIgreja == null)
			listaIgreja = igrejaService.buscarIgrejasPorUsers();
		return listaIgreja;
	}

	public void setListaIgreja(List<Igreja> listaIgreja) {
		this.listaIgreja = listaIgreja;
	}


	public Funcao getFuncaoExerce() {
		return funcaoExerce;
	}


	public void setFuncaoExerce(Funcao funcaoExerce) {
		this.funcaoExerce = funcaoExerce;
	}


	public List<Funcao> getListaFuncaoExerce() {
		return listaFuncaoExerce;
	}


	public void setListaFuncaoExerce(List<Funcao> listaFuncaoExerce) {
		this.listaFuncaoExerce = listaFuncaoExerce;
	}


	public Funcao getFuncao() {
		return funcao;
	}


	public void setFuncao(Funcao funcao) {
		this.funcao = funcao;
	}


	public int getQtFuncaoExerce() {
		return qtFuncaoExerce;
	}


	public void setQtFuncaoExerce(int qtFuncaoExerce) {
		this.qtFuncaoExerce = qtFuncaoExerce;
	}


	public List<Funcao> getListaFuncaoPretendida() {
		return listaFuncaoPretendida;
	}


	public void setListaFuncaoPretendida(List<Funcao> listaFuncaoPretendida) {
		this.listaFuncaoPretendida = listaFuncaoPretendida;
	}


	public int getQtFuncaoPretendida() {
		return qtFuncaoPretendida;
	}


	public void setQtFuncaoPretendida(int qtFuncaoPretendida) {
		this.qtFuncaoPretendida = qtFuncaoPretendida;
	}


	public Funcao getFuncaoPretendida() {
		return funcaoPretendida;
	}


	public void setFuncaoPretendida(Funcao funcaoPretendida) {
		this.funcaoPretendida = funcaoPretendida;
	}
	
	public List<SelectItem> getListaUfs() {
		if(listaUfs == null){
			listaUfs = new ArrayList<SelectItem>();
			for(UfEnum uf: UfEnum.values()){
				listaUfs.add(new SelectItem(uf.getSigla(), uf.getSigla()));
			}
		}
		return listaUfs;
	}

	public void setListaUfs(List<SelectItem> listaUfs) {
		this.listaUfs = listaUfs;
	}


	public Long getCoMembro() {
		return coMembro;
	}


	public void setCoMembro(Long coMembro) {
		this.coMembro = coMembro;
	}

	public boolean isExibirMensagem() {
		return exibirMensagem;
	}

	public void setExibirMensagem(boolean exibirMensagem) {
		this.exibirMensagem = exibirMensagem;
	}

	public List<TipoAdmissaoEnum> getListaTipoAdmissao() {
		if(listaTipoAdmissao == null){
			listaTipoAdmissao = Arrays.asList(TipoAdmissaoEnum.values());// = new ArrayList<SelectItem>();
//			for(TipoAdmissaoEnum tpAdm: TipoAdmissaoEnum.values()){
//				//listaTipoAdmissao.add(new SelectItem(tpAdm, tpAdm.getDescricao()));
//			}
		}
		return listaTipoAdmissao;
	}

	public void setListaTipoAdmissao(List<TipoAdmissaoEnum> listaTipoAdmissao) {
		this.listaTipoAdmissao = listaTipoAdmissao;
	}

	public List<TipoConsagracaoMinisterialEnum> getListaTipoConsagracaoMinisterial() {
			return Arrays.asList(TipoConsagracaoMinisterialEnum.values());
	}

	

	public boolean isRegistrosEncontrados() {
		return registrosEncontrados;
	}

	public void setRegistrosEncontrados(boolean registrosEncontrados) {
		this.registrosEncontrados = registrosEncontrados;
	}

	public Visitante getVisitante() {
		return visitante;
	}

	public void setVisitante(Visitante visitante) {
		this.visitante = visitante;
	}

	public File getFile() {
		if(file == null)
			file = new File();
		return file;
	}

	public void setFile(File file) {
		this.file = file;
	}

	/**
	 * @return the status
	 */
	public String getStatus() {
		return status;
	}

	/**
	 * @param status the status to set
	 */
	public void setStatus(String status) {
		this.status = status;
	}
	
	
	
}
